package com.tykboot.controller;

import com.tykboot.core.base.BaseController;
import com.tykboot.core.persistence.Criteria;
import com.tykboot.core.persistence.Restrictions;
import com.tykboot.entity.*;
import com.tykboot.message.MsgCode;
import com.tykboot.message.ResponseMsg;
import com.tykboot.service.*;
import com.tykboot.vo.AccountVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * Controller
 *
 * @author LiuYu
 */
@Api(tags = "account", description = "/api/accounts")
@RestController
@RequestMapping(BaseController.API + "/accounts")
public class TbAccountController extends BaseController {

    @Autowired
    private ITbAccountService tbAccountService;

    @Autowired
    private ITbAccountDetailService tbAccountDetailService;

    @Autowired
    private ITbAccountServicerService tbAccountServicerService;

    @ApiOperation(value = "Add an account", notes = "Add an account")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "financialId", value = "financialId", dataType = "string", paramType = "header", required = true)
    })
    @PostMapping("")
    public ResponseMsg<TbAccount> add(@RequestHeader("financialId") String financialId,
                                             @RequestBody AccountVo requestBody) {
        ResponseMsg<TbAccount> responseMsg = new ResponseMsg<>();
        TbAccount entity = new TbAccount();
        BeanUtils.copyProperties(requestBody, entity);
        entity.setFinancialId(financialId);
        entity = tbAccountService.save(entity);
        if (entity.getAccount() != null) {
            entity.getAccount().setAccountId(entity.getAccountId());
            tbAccountDetailService.save(entity.getAccount());
        }
        if (entity.getServicer() != null) {
            entity.getServicer().setAccountId(entity.getAccountId());
            tbAccountServicerService.save(entity.getServicer());
        }
        responseMsg.setData(entity);
        return responseMsg;
    }

    @ApiOperation(value = "Update an account", notes = "Update an account")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "financialId", value = "financialId", dataType = "string", paramType = "header", required = true),
            @ApiImplicitParam(name = "accountId", value = "accountId", dataType = "string", paramType = "path", required = true)
    })
    @PutMapping("/{accountId}")
    public ResponseMsg<TbAccount> update(@RequestHeader("financialId") String financialId,
                                      @PathVariable("accountId") String accountId,
                                             @RequestBody AccountVo requestBody) {
        ResponseMsg<TbAccount> responseMsg = new ResponseMsg<>();
        TbAccount entity = tbAccountService.findById(accountId);
        if (entity == null) {
            return new ResponseMsg<>(MsgCode.Param_Error);
        }
        BeanUtils.copyProperties(requestBody, entity, "accountId");
        entity.setFinancialId(financialId);
        entity = tbAccountService.save(entity);
        if (entity.getAccount() != null) {
            entity.getAccount().setAccountId(entity.getAccountId());
            tbAccountDetailService.save(entity.getAccount());
        }
        if (entity.getServicer() != null) {
            entity.getServicer().setAccountId(entity.getAccountId());
            tbAccountServicerService.save(entity.getServicer());
        }
        responseMsg.setData(entity);
        return responseMsg;
    }

    @ApiOperation(value = "Get accounts", notes = "Get accounts")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "financialId", value = "financialId", dataType = "string", paramType = "header", required = true)
    })
    @GetMapping("")
    public ResponseMsg<List<TbAccount>> queryAll(@RequestHeader("financialId") String financialId) {
        ResponseMsg<List<TbAccount>> responseMsg = new ResponseMsg<>();
        Criteria<TbAccount> req = new Criteria<>();
        req.add(Restrictions.eq("financialId", financialId));

        List<TbAccount> tbAccounts = tbAccountService.findAll(req);
        if (tbAccounts != null && !tbAccounts.isEmpty()) {
            for (TbAccount tbAccount : tbAccounts) {
                tbAccount.setAccount(tbAccountDetailService.findById(tbAccount.getAccountId()));
                tbAccount.setServicer(tbAccountServicerService.findById(tbAccount.getAccountId()));
            }
        }
        responseMsg.setData(tbAccounts);
        return responseMsg;
    }

    @ApiOperation(value = "Get an account", notes = "Get an account")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "financialId", value = "financialId", dataType = "string", paramType = "header", required = true),
            @ApiImplicitParam(name = "accountId", value = "accountId", dataType = "string", paramType = "path", required = true)
    })
    @GetMapping("/{accountId}")
    public ResponseMsg<TbAccount> queryAccountById(@RequestHeader("financialId") String financialId,
                                            @PathVariable("accountId") String accountId) {
        ResponseMsg<TbAccount> responseMsg = new ResponseMsg<>();
        Criteria<TbAccount> req = new Criteria<>();
        req.add(Restrictions.eq("accountId", accountId));
        req.add(Restrictions.eq("financialId", financialId));
        List<TbAccount> tbAccounts = tbAccountService.findAll(req);
        if (tbAccounts != null && !tbAccounts.isEmpty()) {
            TbAccount tbAccount = tbAccounts.get(0);
            tbAccount.setAccount(tbAccountDetailService.findById(tbAccount.getAccountId()));
            tbAccount.setServicer(tbAccountServicerService.findById(tbAccount.getAccountId()));
            responseMsg.setData(tbAccount);
        }
        return responseMsg;
    }

    @ApiOperation(value = "Get an account", notes = "Get an account")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "financialId", value = "financialId", dataType = "string", paramType = "header", required = true),
            @ApiImplicitParam(name = "scheme", value = "scheme", dataType = "string", paramType = "header", required = true),
            @ApiImplicitParam(name = "identification", value = "identification", dataType = "string", paramType = "path", required = true)
    })
    @GetMapping("/identification/{identification}")
    public ResponseMsg<TbAccount> queryAccountByIdent(@RequestHeader("financialId") String financialId,
                                                      @RequestHeader("scheme") String scheme,
                                            @PathVariable("identification") String identification) {
        ResponseMsg<TbAccount> responseMsg = new ResponseMsg<>();
        Criteria<TbAccountDetail> req = new Criteria<>();
        req.add(Restrictions.eq("identification", identification));
        req.add(Restrictions.eq("schemeName", scheme));
        List<TbAccountDetail> details = tbAccountDetailService.findAll(req);
        if (details != null && !details.isEmpty()) {
            responseMsg.setData(tbAccountService.findById(details.get(0).getAccountId()));
        }
        return responseMsg;
    }

}
